/******************************************************************************
	This file is a part of the Snapshot Bioinformatics Project

	Copyright (C) 2012-2013 Jarom Schow

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/

#include "Version.h"

using namespace Bio;

///////////////////////////////////////////////////////////////////////////////
//	Version
///////////////////////////////////////////////////////////////////////////////

/**
	@class Version
	@brief General application version representation.

	This is a utility class that provides a representation of an application or library
	version number.
**/

/**
	General Constructor. Creates a new version number with the given values.
	@param	major		The major version number.
	@param	minor		The minor version number.
	@param	revision	The revision number.
	@param	build		The build number.
**/
Version::Version( unsigned short major, unsigned short minor, unsigned short revision, unsigned short build ) : 
	m_major( major ), m_minor( minor ), m_revision( revision ), m_build( build )
{
}

/**
	Copy constructor. Creates a new version number with the same value as the
	given version number.
	@param	version	The version number to create a copy of.
**/
Version::Version( const Version &version ) : m_major( version.m_major ), m_minor( version.m_minor ), 
	m_revision( version.m_revision ), m_build( version.m_build )
{
}

/**
	Destructor.
**/
Version::~Version()
{
}

/**
	Get the major version number.
	@return	The major version number.
**/
unsigned short Version::getMajorVersion() const
{
	return m_major;
}

/**
	Get the minor version number.
	@return	The minor version number.
**/
unsigned short Version::getMinorVersion() const
{
	return m_minor;
}

/**
	Get the revision number.
	@return	The revision number.
**/
unsigned short Version::getRevisionNumber() const
{
	return m_revision;
}

/**
	Get the build number.
	@return	The build number.
**/
unsigned short Version::getBuildNumber() const
{
	return m_build;
}

/**
	Gets a version string. The string returned is either in major.minor format
	e.g. "1.2" or in major.minor.revision.build format e.g. "1.2.3.4". If @p fullVersion
	is true, then all four numbers are given in the version string, otherwise, only the
	first two numbers are given.
	@param	fullVersion	If true, the string will contain all four numbers, otherwise, only
						The major and minor version will be included.
	@return	The version number as a string separated with periods '.'
**/
QString Version::getVersionString( bool fullVersion ) const
{
	QString	version = QString( "%1.%2" ).arg( m_major ).arg( m_minor );

	if( fullVersion )
		version += QString( ".%3.%4" ).arg( m_revision ).arg( m_build );

	return version;
}
/**
	Assignment operator. Makes this version number the same as the given number.
	@param	version	The version number to make this a copy of.
	@return	A reference to this version number.
**/
Version& Version::operator=( const Version &version )
{
	m_major = version.m_major;
	m_minor = version.m_minor;
	m_revision = version.m_revision;
	m_build = version.m_build;

	return *this;
}

/**
	Equality operator. Whether or not this version number is the same as the given
	version number.
	@param	version	The version number to test for equality.
	@return	true is the version numbers are the same, false if they are not.
**/
bool Version::operator==( const Version &version ) const
{
	return (	m_major == version.m_major &&
				m_minor == version.m_minor &&
				m_revision == version.m_revision &&
				m_build == version.m_build );
}

/**
	Less than operator.	Determines whether this version number is less than the given 
	version number.
	@param	version	The version number to compare.
	@return	true if this version number is smaller than the given number, otherwise false.
**/
bool Version::operator<( const Version &version ) const
{
	return packed() < version.packed();
}

/**
	Greater than operator.	Determines whether this version number is higher than the given 
	version number.
	@param	version	The version number to compare.
	@return	true if this version number is higher than the given number, otherwise false.
**/
bool Version::operator>( const Version &version ) const
{
	return packed() > version.packed();
}

/**
	Generates a packed, single value, 64-bit representation of this version number. The high
	16 bits are the major version number, followed by 16 bits for the minor version number,
	16 bits for the revision number, and the low 16 bits are the build number.
	@return	A 64-bit packed representation of this version number.
**/
quint64 Version::packed() const
{
	quint64	val = m_major;

	val <<= 16;
	val += m_minor;
	val <<= 16;
	val += m_revision;
	val <<= 16;
	val += m_build;

	return val;
}
